package com.example;

import org.junit.Test;

import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.*;
import java.util.function.Function;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
import java.util.stream.Stream;

public class StreamGenerate {

    public static final String path = "C:\\Users\\xutao\\Desktop\\essay.txt";

    public String readFile() throws IOException {
        String content = new String(Files.readAllBytes(Paths.get(path)), StandardCharsets.UTF_8);
        return content;
    }





    public void generateStream() throws IOException {
        String[] words = readFile().split("\\PL+");
        //Colletion静态方法streamOf
        Stream<String> stream1 = Arrays.asList(words).stream();
        //Stream的 streamOf静态方法产生流
        Stream<String> stream2 = Stream.of(words);
        //Arrays.stream()方法产生流
        Stream<String> stream3 = Arrays.stream(words);
        //创建不包含任何元素的流
        Stream<Object> stream4 = Stream.empty();
        //创建一个无限流
        Stream<String> stream5 = Stream.generate(() -> "XYZ");
        //创建一个无线序列
        Stream<Integer> stream6 = Stream.iterate(0, t -> t + 2);

        Stream<String> stream7 = Pattern.compile("\\PL+").splitAsStream(readFile());

    }


    public Stream<String> getStream() throws IOException {
        String[] words = readFile().split("\\PL+");
        return Arrays.asList(words).stream();
    }

    public void streamMethods() throws IOException {

        Stream<String> stream1 = getStream().filter(word -> word.length() > 12);

        Stream<String> stream2 = getStream().map(word -> word.toUpperCase());

        Stream<String> stream3 = getStream().map(String::toUpperCase);


    }


    @Test
    public void map() throws IOException {
        Stream<Stream<String>> stream = getStream().map(w -> {
            List<String> list = new LinkedList<>();
            for (int i = 0; i < w.length(); i++) {
                list.add(w.substring(i, i + 1));
            }
            return list.stream();
        });
        stream.forEach(ss ->{
            ss.forEach(w-> System.out.println(w));
            System.out.println("-------------------这是分割线--------------------");
        });
    }

    @Test
    public void flatMap() throws IOException {
        Stream<String> stream = getStream().flatMap(w -> {
            List<String> list = new LinkedList<>();
            for (int i = 0; i < w.length(); i++) {
                list.add(w.substring(i, i + 1));
            }
            return list.stream();
        });
        stream.forEach(System.out::println);
    }

    @Test
    public void limit() throws IOException {
        Stream<String> limit = getStream().limit(3);
        limit.forEach(System.out::println);
    }

    @Test
    public void skip() throws IOException{
        Stream<String> limit = getStream().skip(1).limit(2);
        limit.forEach(System.out::println);
    }

    @Test
    public void concat() throws IOException{
        Stream<String> stream1 = Arrays.stream(new String[]{"H","e","L","L","O"});
        Stream<String> stream2 = Arrays.stream(new String[]{"W","O","R","L","D"});
        Stream<String> concat = Stream.concat(stream1, stream2);
        concat.forEach(System.out::println);
    }

    @Test
    public void distinct() {
        Stream<String> stream1 = Arrays.stream(new String[]{"H","e","L","L","O"});
        Stream<String> stream2 = Arrays.stream(new String[]{"W","O","R","L","D"});
        Stream<String> distinct = Stream.concat(stream1, stream2).distinct();
        distinct.forEach(System.out::println);
    }

    @Test
    public void sort() throws IOException {
        Stream<String> stream = getStream();
//        stream.sorted().forEach(System.out::println);
        stream.sorted((o1,o2)->o1.length()-o2.length()).forEach(System.out::println);
    }

    @Test
    public void max() throws IOException{
        Stream<String> stream = getStream();
        Optional<String> max = stream.max(Comparator.comparing(String::length));
        System.out.println(max.get());
    }

    @Test
    public void findFirst() throws IOException {
        Stream<String> stream = getStream();
        Optional<String> she = stream.filter(s -> s.equals("she")).findFirst();
        System.out.println(she.isPresent());
    }

    @Test
    public void findAny() throws IOException {
        Stream<String> stream = getStream();
        Optional<String> she = stream.filter(s -> s.equals("she")).findAny();
        System.out.println(she.isPresent());
    }

    @Test
    public void anyMatch() throws IOException {
        Stream<String> stream = getStream();
        boolean exist = stream.anyMatch(e -> e.equals("run"));
        System.out.println(exist);
    }

    @Test
    public void collect1() throws IOException {
        Stream<String> stream = getStream();
        //返回list集合
        List<String> list = stream.collect(Collectors.toList());
        //返回set集合
        Set<String> set = stream.collect(Collectors.toSet());
        //返回数组
        String[] ss = stream.toArray(String[]::new);
        //返回特定list
        LinkedList<String> linkedList = stream.collect(Collectors.toCollection(LinkedList::new));
        //组合成string返回
        String str1 = stream.collect(Collectors.joining());
        //增加分隔符后返回string
        String str2 = stream.collect(Collectors.joining(","));

        IntSummaryStatistics summaryInt = stream.collect(Collectors.summarizingInt(Integer::new));
        double average = summaryInt.getAverage();
        long count = summaryInt.getCount();
        int max = summaryInt.getMax();
        int min = summaryInt.getMin();
    }

    @Test
    public void t1(){
        Stream<Locale> stream = Stream.of(Locale.getAvailableLocales());
        Map<String, String> map = stream.collect(Collectors.toMap(Locale::getDisplayLanguage, Locale::getDisplayLanguage, (ev, nv) -> ev));
        System.out.println(map);
    }

    @Test
    public void t2(){
        Stream<Locale> stream = Stream.of(Locale.getAvailableLocales());
        Map<String, Set<String>> collect = stream.collect(Collectors.toMap(Locale::getDisplayCountry,
                l -> Collections.singleton(l.getDisplayLanguage()),
                (a, b) -> {
                    Set<String> union = new HashSet<>(a);
                    union.addAll(b);
                    return union;
                }));
        for (Map.Entry<String, Set<String>> entry : collect.entrySet()) {
            System.out.println("Country:"+entry.getKey());
            System.out.println("Value:"+Arrays.toString(entry.getValue().toArray()));
        }

    }


    public Stream<Person> t3bf(){
        return Stream.of(new Person(1, "Marry"), new Person(2, "Mourd"), new Person(3, "Cherr"));
    }
    @Test
    public void t3(){
        Stream<Person> st1 = t3bf();
        Map<Integer, String> map1 = st1.collect(Collectors.toMap(Person::getId, Person::getName));
        Stream<Person> st2 = t3bf();
        Map<Integer, Person> map2 = st2.collect(Collectors.toMap(Person::getId, Function.identity()));
    }

    @Test
    public void t4(){
        Stream<Locale> stream = Stream.of(Locale.getAvailableLocales());
        Map<String, List<Locale>> collect = stream.collect(Collectors.groupingBy(Locale::getDisplayCountry));
        for (Map.Entry<String, List<Locale>> entry : collect.entrySet()) {
            System.out.println("Country:"+entry.getKey());
            System.out.println("Value:"+Arrays.toString(entry.getValue().toArray()));
        }

    }


    @Test
    public void t5() {
        Stream<Locale> stream = Stream.of(Locale.getAvailableLocales());
        Map<Boolean, List<Locale>> collect = stream.collect(Collectors.partitioningBy(l -> l.getLanguage().equals("en")));
        for (Map.Entry<Boolean, List<Locale>> entry : collect.entrySet()) {
            System.out.println("Country:"+entry.getKey());
            System.out.println("Value:"+Arrays.toString(entry.getValue().toArray()));
        }
    }
}
